`include "timescale.v"

module onu_classifier(
	input 		   reset,
	input 		   Rx_clk,
	input  [7:0]   Rxd_mac,
	
	input  [4:0]   rx_state,
	input  [15:0]  rx_byte_cnt,
	input 		   rx_fcs_ok,

	// output reg 	   gate_discovery_frame, gate_normal_frame, register_frame, data_frame;
	output [3:0]   rx_frame_type,

	input  [47:0]  LOCAL_MAC_ADDR
	);

localparam 		  FRAME_BUFFER_DEPTH = 32;
reg 	  [7:0]   rx_frame_buffer [FRAME_BUFFER_DEPTH-1:0];

wire 			  gate_discovery_frame, gate_normal_frame, register_frame, data_frame;
assign 			  rx_frame_type[3:0] = {gate_discovery_frame, gate_normal_frame, register_frame, data_frame};




always@(posedge Rx_clk or posedge reset)
begin
  if(rx_state`RxDATA & rx_byte_cnt<FRAME_BUFFER_DEPTH)
	rx_frame_buffer[rx_byte_cnt] <= Rxd_mac;
end



////////////////////////////////////////////////////////////////////////////////////////////////////
wire 	  [15:0]  eth_len_type;
// assign 			  eth_len_type 	  = rx_frame_buffer`ETH_LEN_TYPE;
// assign 			  eth_len_type 	  = rx_frame_buffer[13:12];
assign 			  eth_len_type = {rx_frame_buffer[12], rx_frame_buffer[13]};
wire 	  [47:0]  eth_DA;
assign 			  eth_DA 	  = {rx_frame_buffer[0], rx_frame_buffer[1], rx_frame_buffer[2], rx_frame_buffer[3], rx_frame_buffer[4], rx_frame_buffer[5]};

wire 	  [15:0]  mpcp_opcode;
assign 			  mpcp_opcode = {rx_frame_buffer[14], rx_frame_buffer[15]};

wire 	  [31:0]  mpcp_timestamp;
assign 			  mpcp_timestamp = {rx_frame_buffer[16], rx_frame_buffer[17], rx_frame_buffer[18], rx_frame_buffer[19]};

wire 	  [7:0]   mpcp_gate_grant_num;
assign 			  mpcp_gate_grant_num = rx_frame_buffer[20];

wire 	  [31:0]  mpcp_gate_grant1_starttime;
assign 			  mpcp_gate_grant1_starttime = {rx_frame_buffer[21], rx_frame_buffer[22], rx_frame_buffer[23], rx_frame_buffer[24]};
wire 	  [15:0]  mpcp_gate_grant1_length;
assign 			  mpcp_gate_grant1_length = {rx_frame_buffer[25], rx_frame_buffer[26]};

wire 	  [15:0]  mpcp_register_port;			//the LLID
assign 			  mpcp_register_port = {rx_frame_buffer[20], rx_frame_buffer[21]};
wire 	  [7:0]   mpcp_register_flag;
assign 			  mpcp_register_flag = rx_frame_buffer[22];
wire 	  [15:0]  mpcp_register_synctime;
assign 			  mpcp_register_synctime = {rx_frame_buffer[23], rx_frame_buffer[24]};
wire 	  [7:0]   mpcp_register_echoed_pending_grants;
assign 			  mpcp_register_echoed_pending_grants = rx_frame_buffer[25];

// wire 	  [7:0]   slow_protocol_subtype;
// assign 			  slow_protocol_subtype = rx_frame_buffer[];

//////////////////////////////
assign 			  gate_discovery_frame = rx_fcs_ok & eth_DA==48'h0180_c200_0001 & eth_len_type==16'h8808 & mpcp_opcode==16'h0002 & mpcp_gate_grant_num[3];

assign 			  gate_normal_frame = rx_fcs_ok & eth_DA==48'h0180_c200_0001 & eth_len_type==16'h8808 & mpcp_opcode==16'h0002 & ~mpcp_gate_grant_num[3];

assign 			  register_frame = rx_fcs_ok & eth_DA==LOCAL_MAC_ADDR & eth_len_type==16'h8808 & mpcp_opcode==16'h0005;
assign 			  data_frame  = rx_fcs_ok & eth_DA==LOCAL_MAC_ADDR & eth_len_type<=16'h05DC;
//////////////////////////////

// //classifier, only checked when the FCS is ok			//should not a sequential circuit ???
// always@(posedge Rx_clk or posedge reset)
// begin
//   if(rx_fcs_ok)
//   begin
// 	if(eth_DA==48'h0180_c200_0001)
// 	begin
// 	  if(eth_len_type==16'h8808)				//MPCP & PAUSE frame
// 	  begin
// 		if(mpcp_opcode==16'h0002)			//gate frame
// 		begin
// 		  gate_discovery_frame <= mpcp_gate_grant_num[3];
// 		  gate_normal_frame <= ~mpcp_gate_grant_num[3];
// 		end
// 	  end
// 	end
// 	// else if(eth_DA==48'h0180_c200_0002)			//check for OAM frame
// 	//   if(eth_len_type==16'h8809)

// 	else if(eth_DA==LOCAL_MAC_ADDR)
// 	begin
// 	  if(eth_len_type==16'h8808 & mpcp_opcode==16'h0005) begin
// 		register_frame <= 1'b1;
// 	  end
// 	  else if(eth_len_type<=16'h05DC)
// 		data_frame <= 1'b1;
// 	end
//   end
// end

  
////////////////////////////////////////////////////////////////////////////////////////////////////
// data_frame
//gate_discovery_frame
//gate_normal_frame
//register_frame
//oam_frame

			  
endmodule // onu_classifier
